package ua.kpi_java_training.zabrodskyi.module2;

/**
 * @author Maksym Zabrodskyi
 * @version 10-Jun-2013
 */
public class Victim extends Fish implements Move {

    private final int STEP_OF_MOVE = 1;
    private final int STEP_OF_SPAWN = 10;
    private int counterMoves = 0;

    public Victim() {
        super();
    }

    public Victim(Position position) {
        super(position);
    }

    @Override
    public void move(Pool pool) {
        Position newPosition = new Position();
        newPosition.setPosition(this.getPosition());
        if (isPossibleMove(pool)) {
            chooseNewPosition(pool, newPosition);
            countMove();
        }
        this.setPosition(newPosition);
    }

    private boolean isPossibleMove(Pool pool) {
        int x = this.getPosition().getX();
        int y = this.getPosition().getY();
        boolean possibility = false;
        if (pool.isFreePosition(new Position(x - STEP_OF_MOVE, y))
                || pool.isFreePosition(new Position(x + STEP_OF_MOVE, y))
                || pool.isFreePosition(new Position(x, y - STEP_OF_MOVE))
                || pool.isFreePosition(new Position(x, y + STEP_OF_MOVE))) {
            possibility = true;
        }
        return possibility;
    }

    private void chooseNewPosition(Pool pool, Position newPosition) {
        do {
            newPosition.setPosition(this.getPosition());
            int x = newPosition.getX();
            int y = newPosition.getY();
            switch (Random.getDirection()) {
                case LEFT:
                    newPosition.setX(x - STEP_OF_MOVE);
                    break;
                case RIGHT:
                    newPosition.setX(x + STEP_OF_MOVE);
                    break;
                case UP:
                    newPosition.setY(y - STEP_OF_MOVE);
                    break;
                case DOWN:
                    newPosition.setY(y + STEP_OF_MOVE);
                    break;
                default:
                    break;
            }
        } while (pool.isBadPosition(newPosition));
    }

    private void countMove() {
        counterMoves++;
    }

    @Override
    public void spawn(Pool pool) {
        if (counterMoves % STEP_OF_SPAWN == 0 && pool.hasFreeUnit()) {
            Victim victim = new Victim();
            victim.setPosition(Random.getFreePosition(pool));
            pool.add(victim);
            Statistics.countSpawnedVictim();
            Printer.printToConsole("~ New Victim was born - "
                    + victim.toString());
        }
    }

    @Override
    public void eat(Pool pool) {
    }

    @Override
    public void ruin(Pool pool) {
        printRuin();
        Statistics.countRuinedVictim();
        pool.remove(this);
    }

    private void printRuin() {
        String dash = String.format("%0" + 5 + "d", 0).replace("0", "x ");
        Printer.printToConsole(dash + "This Victim was ruined - "
                + this.toString());
    }

    @Override
    public boolean equals(Object object) {
        return (object instanceof Victim);
    }

    @Override
    public String toString() {
        return String.format("Victim is on position %s", super.getPosition());
    }

}
